# camera_recognizer.py
from mcp.server.fastmcp import FastMCP
import sys
import logging
import subprocess
import time
import cv2
import tempfile
import os

logger = logging.getLogger('CameraRecognizer')

# 修复Windows控制台UTF-8编码
if sys.platform == 'win32':
    sys.stderr.reconfigure(encoding='utf-8')
    sys.stdout.reconfigure(encoding='utf-8')

# 创建MCP服务器
mcp = FastMCP("CameraRecognizer")

def capture_image(resolution=(320, 240)):  # 修改默认分辨率为320x240
    """捕获摄像头图像并返回临时文件路径"""
    # 优先使用DSHOW加速Windows摄像头访问速度
    cap = None
    try:
        if sys.platform == 'win32':
            cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        else:
            cap = cv2.VideoCapture(0)
            
        if not cap.isOpened():
            raise Exception("无法打开摄像头")
        
        # 强制设置为320x240分辨率
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
        
        # 多捕获几帧确保画面稳定
        for _ in range(2):
            cap.read()
        
        ret, frame = cap.read()
        if not ret:
            raise Exception("无法捕获图像")
        
        # 保存到临时文件（降低JPG质量加快传输）
        temp_file = tempfile.NamedTemporaryFile(suffix='.jpg', delete=False)
        cv2.imwrite(temp_file.name, frame, [int(cv2.IMWRITE_JPEG_QUALITY), 70])
        temp_file.close()
        
        return temp_file.name
    finally:
        if cap:
            cap.release()
        cv2.destroyAllWindows()

def capture_video(duration=5, resolution=(320, 240)):  # 修改默认分辨率为320x240
    """录制视频并返回临时文件路径（仅保存第一帧用于识别）"""
    return capture_image_image(resolution)  # 复用图像捕获逻辑

def call_ollama(image_path):
    """调用本地ollama的qwen2.5vl模型，优化超时处理"""
    try:
        command = [
            "ollama", "run", "qwen2.5vl",
            "简要描述图像内容，不超过80字：{{image}}"  # 缩短提示词减少处理时间
        ]
        
        process = subprocess.Popen(
            command,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            encoding='utf-8'
        )
        
        # 缩短超时时间至10秒，配合低分辨率提升响应速度
        try:
            stdout, stderr = process.communicate(input=image_path, timeout=10)
        except subprocess.TimeoutExpired:
            process.kill()
            return {"success": False, "error": "识别超时，请重试（已降低分辨率优化）"}
        
        if process.returncode != 0:
            return {"success": False, "error": stderr}
        
        return {"success": True, "result": stdout.strip()}
    except Exception as e:
        return {"success": False, "error": str(e)}

@mcp.tool()
def 图像捕获与识别(mode: str = "photo", resolution: str = "320x240") -> dict:
    """
    图像捕获与识别工具 - 通过摄像头拍摄照片或视频，并使用本地qwen2.5vl模型进行内容解析
    
    该功能采用低分辨率优化策略，以确保快速响应和良好性能。
    支持两种工作模式：照片拍摄和视频录制（视频模式仅处理第一帧）。
    内部会对拍摄的图像进行压缩处理，并调用本地Ollama服务进行智能识别。
    
    参数:
        mode: 工作模式，可选值为"photo"(拍照)或"video"(录像，实际只处理第一帧)
        resolution: 分辨率参数（当前版本已强制使用320x240以优化性能）
    返回值:
        字典类型，包含识别结果或错误信息，格式为{"success": 布尔值, "result/error": 字符串}
    """
    try:
        # 强制使用320x240分辨率，忽略传入的其他值
        width, height = 320, 240
        logger.info(f"使用优化分辨率: {width}x{height}")
        
        # 捕获图像
        start_time = time.time()
        if mode == "photo":
            image_path = capture_image((width, height))
        else:
            image_path = capture_video(resolution=(width, height))
        logger.info(f"图像捕获耗时: {time.time() - start_time:.2f}秒")
        
        # 调用Ollama识别
        start_time = time.time()
        result = call_ollama(image_path)
        logger.info(f"模型识别耗时: {time.time() - start_time:.2f}秒")
        
        # 清理临时文件
        os.unlink(image_path)
        
        return result
    
    except Exception as e:
        logger.error(f"处理失败: {str(e)}")
        return {"success": False, "error": str(e)}

if __name__ == "__main__":
    # 启动服务器
    mcp.run(transport="stdio")